package com.shenfc.fxzj.util;

import org.apache.commons.lang3.StringUtils;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 日期工具类
 * @author zhengli08275
 *
 */
public class DateUtils {
	public static long ONE_DAY = 24 * 3600000;
	public static long ONE_MINUTE = 60000;// 分
	public static long ONE_HOUR = 3600000;// 小时
	/**
	 * yyyyMMdd
	 * */
	public static final String DATE_BANK_FORMAT = "yyyyMMdd";
	/**
	 * yyyyMMddHH
	 * */
	public static final String DATE_BANK2_FORMAT = "yyyyMMddHH";
	/**
	 * yyyy-MM-dd
	 * */
	public static final String DATE_FORMAT = "yyyy-MM-dd";
	/**
	 * yyyy-MM-dd HH:mm:ss
	 * */
	public static final String DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
	public static final String DATETIME_FORMATA = "yyyy-MM-dd hh:mm:ss";
	/**
	 * yyyy-MM-dd HH:mm
	 * */
	public static final String DATETIME1_FORMAT = "yyyy-MM-dd HH:mm";
	/**
	 * yy-MM-dd HH:mm
	 * */
	public static final String DATETIME2_FORMAT = "yy-MM-dd HH:mm";
	/**
	 * yyyyMMddHHmmss
	 * */
	public static final String DATETIME3_FORMAT = "yyyyMMddHHmmss";
	/**
	 * yyyyMMddHHmmssSSS 年月日时分秒毫秒
	 */
	public static final String DATATIME4_FORMAT = "yyyyMMddHHmmssSSS";
	/**
	 * yyyy年MM月dd日 HH:mm:ss
	 * */
	public static final String DATETIME4_FORMAT = "yyyy年MM月dd日 HH:mm:ss";

	/**
	 * yy年MM月dd日 HH:mm
	 * */
	public static final String DATETIME5_FORMAT = "yy年MM月dd日 HH:mm";

	/**
	 * yy年MM月dd日
	 * */
	public static final String DATETIME6_FORMAT = "yy年MM月dd日";
	
	/**
	 * yyyy-MM-dd HH 
	 * 命名有问题，谁的接口有调用就改下下面的静态变量
	 * */
	@Deprecated
	public static final String DATETIM7_FORMAT = "yyyy-MM-dd HH";
	
	/**
	 * yyyy-MM-dd HH
	 * */
	public static final String DATETIME7_FORMAT = "yyyy-MM-dd HH";
	
	/**
	 * HH:mm
	 * */
	public static final String DATETIME8_FORMAT = "HH:mm";
	
	/**
	 * 星期信息
	 */
	public static final String WEEK_FORMAT = "EEE";
	/**
	 * 日期转字符串
	 * @param format
	 * @param date
	 * @return
	 */
	public static String dateToString(String format,Date date){
		if(date!=null){
			SimpleDateFormat sdf=new SimpleDateFormat(format);
			return sdf.format(date);
		}
		return "";
	}
	
	/**
	 * 字符串转日期
	 * @param format
	 * @param str
	 * @return
	 * @throws ParseException
	 */
	public static Date stringToDate(String format,String str) throws ParseException{
		SimpleDateFormat sdf=new SimpleDateFormat(format);
		return sdf.parse(str);
	}
	
	public static Date addSecond(Date date, int i) {
		Calendar c = Calendar.getInstance();

		c.setTime(date);
		c.add(Calendar.SECOND, i);
		return c.getTime();
	}

	public static Date addMinute(Date date, int i) {
		Calendar c = Calendar.getInstance();

		c.setTime(date);
		c.add(Calendar.MINUTE, i);
		return c.getTime();
	}

	public static Date addMonth(Date date, int i) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(Calendar.MONTH, i);
		return c.getTime();
	}

	public static Date addDay(Date date, int i) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(Calendar.DATE, i);
		return c.getTime();
	}

	public static Date addYear(Date date, int i) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(Calendar.YEAR, i);
		return c.getTime();
	}

	public static Date firstDayOfMonth(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.set(Calendar.DAY_OF_MONTH, 1);
		return c.getTime();
	}

	public static Date lastDayOfMonth(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.set(Calendar.DAY_OF_MONTH, 1);
		c.add(Calendar.MONTH, 1);
		c.add(Calendar.DATE, -1);
		return c.getTime();
	}

	public static int getYear(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.get(Calendar.YEAR);
	}

	public static int getMonth(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.get(Calendar.MONTH);
	}

	public static int getDay(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.get(Calendar.DAY_OF_MONTH);
	}

	/**
	 * 得到当前日期字符串
	 * 
	 * @return
	 */
	public static String getTodayString() {
		return toDateString(new Date());
	}

	/**
	 * 得到当前日期字符串
	 * 
	 * @return
	 */
	public static String getTodayString(String dateFormat) {
		return toDateString(new Date(), dateFormat);
	}

	/**
	 * 得到当前日期字符串
	 * 
	 * @return
	 */
	public static String getNextDayDate() {
		Calendar cal = Calendar.getInstance();
		cal.setTime(new Date());
		cal.add(Calendar.DATE, 1);
		return new SimpleDateFormat("yyyy-MM-dd").format(cal.getTime());
	}

	public static String getAfterTomorrowDate() {
		Calendar cal = Calendar.getInstance();
		cal.setTime(new Date());
		cal.add(Calendar.DATE, 2);
		return new SimpleDateFormat("yyyy-MM-dd").format(cal.getTime());
	}

	public static String getAfterThreeDate() {
		Calendar cal = Calendar.getInstance();
		cal.setTime(new Date());
		cal.add(Calendar.DATE, 3);
		return new SimpleDateFormat("yyyy-MM-dd").format(cal.getTime());
	}

	public static String getAfterThreeSimpleDate() {
		Calendar cal = Calendar.getInstance();
		cal.setTime(new Date());
		cal.add(Calendar.DATE, 3);
		return new SimpleDateFormat("MM-dd").format(cal.getTime());
	}

	/**
	 * 得到当前日期字符串
	 * 
	 * @return
	 */
	public static String getNextDayDateTime() {
		Calendar cal = Calendar.getInstance();
		cal.setTime(new Date());
		cal.add(Calendar.DATE, 1);
		return new SimpleDateFormat(DATETIME_FORMAT).format(cal.getTime());
	}

	/**
	 * 将Timestamp的实例转换为date型字符串
	 * 
	 * @param
	 * @return
	 */
	public static String toDateString(Date date) {
		return toDateString(date, DATE_FORMAT);
	}

	/**
	 * 将日期转换为指定格式的字符串
	 * 
	 * @param date
	 * @param dateFormat
	 * @return
	 */
	public static String toDateString(Date date, String dateFormat) {
		if (date != null) {
			SimpleDateFormat format = new SimpleDateFormat(dateFormat);
			String dateString = format.format(date);
			return dateString;
		}
		return null;
	}

	/**
	 * 将日期字符串转换为日期
	 * 
	 * @param dateString
	 * @return
	 * @throws Exception
	 */
	public static Date toDate(String dateString) throws Exception {
		return toDate(dateString, DATE_FORMAT);
	}

	/**
	 * 将日期字符串按指定格式转换为日期
	 * 
	 * @param dateString
	 * @param dateFormat
	 * @return
	 * @throws ParseException
	 * @throws Exception
	 */
	public static Date toDate(String dateString, String dateFormat)
			throws ParseException {
		SimpleDateFormat format = new SimpleDateFormat(dateFormat);
		return format.parse(dateString);
	}
 

	/**
	 * 将日期转换为缺省方式的datetime格式
	 * 
	 * @param date
	 * @return
	 */
	public static String toDatetimeString(Date date) {
		return toDateString(date, DATETIME_FORMAT);
	}
	
	
	public static String toDatetimeStringI(Date date) {
		return toDateString(date, DATETIME1_FORMAT);
	}


	public static int getDaysBetween(Date date1, Date date2) {
		try {
			SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);

			double days = (sdf.parse(sdf.format(date1)).getTime() - sdf.parse(
					sdf.format(date2)).getTime())
					/ (24 * 3600000f);

			if (days < 0)
				days = -days;
			return (int) Math.ceil(days);

		} catch (ParseException e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * 判断是当前时间是否在两时间段之间
	 * 
	 * @param
	 * @return
	 */
	public static boolean getIsCurrentimeBetween(String fromTime, String toTime) {
		try {
			Date fromDate = toDate(getTodayString() + " " + fromTime,
					DATETIME_FORMAT);
			Date toDate = toDate(getTodayString() + " " + toTime,
					DATETIME_FORMAT);
			if (getTimeSpaceMilli(fromDate) > 0
					&& getTimeSpaceMilli(toDate) < 0) {
				return true;
			} else {
				return false;
			}
		} catch (ParseException e) {
			throw new RuntimeException(e);
		}
	}
	
	/**
	 * 判断时间是否在两个时间范围内
	 * @param fromTime
	 * @param toTime
	 * @param checkTime
	 * @return
	 */
	public static boolean getIsTimeBetween(String fromTime, String toTime, String checkTime){
		try {
			Date checkDate = toDate(checkTime,DATETIME_FORMAT);
			return getIsTimeBetween(fromTime, toTime, checkDate);
		} catch (ParseException e) {
			throw new RuntimeException(e);
		}
	}
	
	/**
	 * 判断时间是否在两个时间范围内
	 * @param fromTime
	 * @param toTime
	 * @param checkDate
	 * @return
	 */
	public static boolean getIsTimeBetween(String fromTime, String toTime, Date checkDate){
		try {
			Date fromDate = toDate(getTodayString() + " " + fromTime,
					DATETIME_FORMAT);
			Date toDate = toDate(getTodayString() + " " + toTime,
					DATETIME_FORMAT);
			return getIstimeBetween(fromDate, toDate, checkDate);
		} catch (ParseException e) {
			throw new RuntimeException(e);
		}
	}
	
	/**
	 * 判断时间是否在两个时间范围内
	 * @param fromDate
	 * @param toDate
	 * @param checkDate
	 * @return
	 */
	public static boolean getIstimeBetween(Date fromDate, Date toDate, Date checkDate) {
		if (getTimeSpaceMilli(fromDate,checkDate) > 0
				&& getTimeSpaceMilli(toDate,checkDate) < 0) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 生成未来几天的日期列表.
	 * 
	 * @param days
	 *            天数
	 * @return 日期的字符串列表.
	 */
	public static List<String> getDateList(int days) {
		List<String> dates = new ArrayList<String>();
		Date d = new Date();
		for (int i = 0; i < days; i++) {
			Date nextDay = addDay(d, i + 1);
			dates.add(toDateString(nextDay));
		}
		return dates;
	}

	/**
	 * 将日期字符串转换为日期的毫秒数.
	 * 
	 * @param dateString
	 * @param dateFormat
	 * @return 日期的毫秒数
	 * @throws Exception
	 */
	public static long dateStringToLong(String dateString, String dateFormat)
			throws Exception {
		Date date = toDate(dateString, dateFormat);
		return date.getTime();
	}

	/**
	 * 
	 * @函数名称：toNomalStringOfDate
	 * @功能描述：String型的日期转换成10位的标准日期
	 * @param strDate
	 * @return
	 */
	public static String toNomalStringOfDate(String strDate) {
		java.sql.Date d = stringToSqlDate(strDate);
		return toDateString(d);
	}

	/**
	 * stringToSqlDate 将String转换成sql日期类型。
	 * 
	 * @param
	 * @return Date
	 */
	public static java.sql.Date stringToSqlDate(String str) {
		if (stringToUtilDate(str) == null || str.length() < 1)
			return null;
		else
			return new java.sql.Date(stringToUtilDate(str).getTime());
	}

	/**
	 * stringToUtilDate 将String转换成日期格式。
	 * 
	 * @param
	 * @return Date
	 */
	public static Date stringToUtilDate(String str) {
		if (null != str && str.length() > 0) {
			try {
				// 对两种时间格式进行转化。
				if (str.length() <= DATE_FORMAT.length()) { // 只包含日期。
					return (new SimpleDateFormat(DATE_FORMAT)).parse(str);
				} else { // 日期和时间都有
					return (new SimpleDateFormat(DATE_FORMAT)).parse(str);
				}
			} catch (Exception ex) {
				return null;
			}
		} else
			return null;
	}

	public static String toDateString(java.sql.Date d) {
		if (d == null) {
			return null;
		} else {
			return (new SimpleDateFormat(DATE_FORMAT)).format(d);
		}
	}

	/**
	 * 任意格式字符串日期转换成Date类型
	 * 
	 * @param
	 * @return Date
	 */
	public static Date toDate4AnyFmt(String strDate) throws ParseException {

		Date result = null;
		String parse = strDate;
		parse = parse.replaceFirst("^[0-9]{4}([^0-9]?)", "yyyy$1");
		parse = parse.replaceFirst("^[0-9]{2}([^0-9]?)", "yy$1");
		parse = parse.replaceFirst("([^0-9]?)[0-9]{1,2}([^0-9]?)", "$1MM$2");
		parse = parse.replaceFirst("([^0-9]?)[0-9]{1,2}( ?)", "$1dd$2");
		parse = parse.replaceFirst("( )[0-9]{1,2}([^0-9]?)", "$1HH$2");
		parse = parse.replaceFirst("([^0-9]?)[0-9]{1,2}([^0-9]?)", "$1mm$2");
		parse = parse.replaceFirst("([^0-9]?)[0-9]{1,2}([^0-9]?)", "$1ss$2");
		DateFormat format = new SimpleDateFormat(parse);
		result = format.parse(strDate);
		return result;
	}

	/**
	 * 获取当前时间延迟后的时间
	 * @param delayTime
	 * @return
	 */
	public static long getTimeMillisAfterDelay(long delayTime){
		return (System.currentTimeMillis() + delayTime);
	}
	
	public static Date getTimeAfterDelay(long delayTime){
		return new Date(System.currentTimeMillis() + delayTime);
	}
	
	/**
	 * 取得当前时间与指定时间的差的分钟数
	 * 
	 * @param fromDate
	 * @return
	 */
	public static long getTimeSpaceMinute(Date fromDate) {
		long fromDateMilli = fromDate.getTime();
		// 当前时间的毫秒数
		long nowTimeMilli = System.currentTimeMillis();
		long timeSpace = (nowTimeMilli - fromDateMilli) / ONE_MINUTE;
		return timeSpace;
	}

	/**
	 * 取得当前时间与指定时间的差的毫秒数
	 * 
	 * @param fromDate
	 * @return
	 */
	public static long getTimeSpaceMilli(Date fromDate) {
		long fromDateMilli = fromDate.getTime();
		// 当前时间的毫秒数
		long nowTimeMilli = System.currentTimeMillis();
		long timeSpace = nowTimeMilli - fromDateMilli;
		return timeSpace;
	}
	/**
	 * 取得两个时间的时间差的毫秒数
	 *
	 * @param fromDate
	 * @param toDate
	 * @return 时间差的分钟数
	 */
	public static long getTimeSpaceMilli(Date fromDate, Date toDate) {
		long fromDateMilli = fromDate.getTime();
		long toDateMilli = toDate.getTime();
		long timeSpace = (toDateMilli - fromDateMilli);
		return timeSpace;
	}

	/**
	 * 取得两个时间的时间差的分钟数
	 * 
	 * @param fromDate
	 * @param toDate
	 * @return 时间差的分钟数
	 */
	public static long getTimeSpaceMinute(Date fromDate, Date toDate) {
		long fromDateMilli = fromDate.getTime();
		long toDateMilli = toDate.getTime();
		long timeSpace = (toDateMilli - fromDateMilli) / ONE_MINUTE;
		return timeSpace;
	}

	/**
	 * 根据日期获取星期几
	 * 
	 * @param dateStr
	 * @return
	 */
	public static String getWeekDate(String dateStr) {
		Date date = stringToUtilDate(dateStr);
		DateFormat df = new SimpleDateFormat(WEEK_FORMAT,Locale.CHINA );
		return df.format(date);
	}

	 

	/**
	 * 去掉时分秒
	 * 
	 * @param dt
	 *            时间
	 * @return 返回 按指定格式转换后的时间
	 */
	public static Date getformatData(Date dt, String dateFormat) {
		try {
			SimpleDateFormat format = new SimpleDateFormat(dateFormat);
			String dateString = format.format(dt);
			Date date = format.parse(dateString);
			return date;
		} catch (Exception ex) {
			throw new RuntimeException(ex);
		}

	}

	public static String getThirtyAfter() {

		Date dNow = new Date(); // 当前时间
		Date dBefore = new Date();
		Calendar calendar = Calendar.getInstance(); // 得到日历
		calendar.setTime(dNow);// 把当前时间赋给日历
		calendar.add(Calendar.MINUTE, 30); // 设置30分钟之后月
		dBefore = calendar.getTime();
		SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm");
		return sd.format(dBefore);
	}

	public static Date getTimeAfterSecond(Date date,int second) {
		Calendar calendar = Calendar.getInstance(); //得到日历
		calendar.setTime(date);// 把当前时间赋给日历
		calendar.add(Calendar.SECOND, second); //
		return calendar.getTime();
	}
	
	public static Date getTimeAfterMinute(Date date,int minute) {
		Calendar calendar = Calendar.getInstance(); //得到日历
		calendar.setTime(date);// 把当前时间赋给日历
		calendar.add(Calendar.MINUTE, minute); //
		return calendar.getTime();
	}
	
	public static Date getTimeAfterHour(Date date,int hour) {
		Calendar calendar = Calendar.getInstance(); //得到日历
		calendar.setTime(date);// 把当前时间赋给日历
		calendar.add(Calendar.HOUR, hour); //
		return calendar.getTime();
	}
	
	public static String getTomorrowFormat(){
		Date date=new Date();//取时间
		Calendar calendar =  Calendar.getInstance();
		 calendar.setTime(date);
		 calendar.add(calendar.DATE,1);//把日期往后增加一天.整数往后推,负数往前移动
		 date=calendar.getTime(); //这个时间就是日期往后推一天的结果 
		 SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
		 String dateString = formatter.format(date);
		return dateString;
	}	
	

	public static String getDayFormat(Date date) {
		if (date == null)
			return "";
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		String ret = format.format(date);
		return ret;
	}

	public static String showDay(Date date) {
		SimpleDateFormat bartDateFormat = new SimpleDateFormat("MM月dd日");
		String ret = bartDateFormat.format(date);
		return ret;
	}

	public static String showWeek(Date date) { 
		 
		 
		Calendar calendar = Calendar.getInstance(); // 得到日历
		calendar.setTime(date);// 把当前时间赋给日历
		SimpleDateFormat bartDateFormat = new SimpleDateFormat("EEEE");

		String ret = bartDateFormat.format(calendar.getTime());
		return ret;
	}
	public static List<Date> getAfterDate(int day){ 
		 
		Calendar calendar = Calendar.getInstance(); // 得到日历
		List<Date> list=new ArrayList<Date>();
		if(day<=0){
			return list;
		}
		for(int i=0;i<=day;i++ ){
			list.add(calendar.getTime());
			calendar.add(Calendar.DATE, 1); 
			
		}
		return list; 
	}
	
	public static String toDateString(String dateStr, String dateFormat) {
		String dateString = "";
		SimpleDateFormat format = new SimpleDateFormat(dateFormat);
		Date date;
		try {
			date = format.parse(dateStr);
			dateString = format.format(date);
		} catch (ParseException e) {
			throw new RuntimeException(e);
		}			
		return dateString;
	}
	
	/**
	 * 得到当前时间
	 * 
	 * @return
	 */
	public static Timestamp getCurrentTime() {
		return new Timestamp((new Date()).getTime());
	}
	
	/**
	 * 日期是否是今天
	 */
	public static boolean isToday(Date date) {
		String today = new SimpleDateFormat("yyyyMMdd")
				.format(getCurrentTime());
		String strDate = new SimpleDateFormat("yyyyMMdd").format(date);

		return today.equals(strDate);
	}
	public static void main(String[] args) {
		System.out.println(getTomorrowFormat());
		
	}
	
	/**
	 * 枚举按日期,按小时,按分钟
	 * @author zhengli08275
	 *
	 */
	public enum OVERDAY_CHECK_TYPE{
		DAY,HOUR,MINUTE
	}

	/**
	 * 是否nextDay大于frontDay
	 * @param frontDateStr
	 * @param nextDateStr
	 * @param type	类型:DAY按日期判断,HOUR按小时判断,MINUTE按分钟判断
	 * @return
	 */
	public static boolean isOverDay(String frontDateStr ,String nextDateStr, OVERDAY_CHECK_TYPE type) throws ParseException{
		return isOverDay(frontDateStr, nextDateStr, type, false);
	}
	
	public static boolean isOverDay(String frontDateStr ,String nextDateStr, OVERDAY_CHECK_TYPE type, boolean isContainEqual) throws ParseException{
		if(StringUtils.isBlank(frontDateStr)||StringUtils.isBlank(nextDateStr))
			return false;
		String format = DATETIME1_FORMAT;
		switch(type){
			case DAY:
				format = DATE_FORMAT;
				break;
			case HOUR:
				format = DATETIM7_FORMAT;
				break;
			case MINUTE:
//				format = DATETIME1_FORMAT;
				break;
		}
			Date dateFront = stringToDate(format, frontDateStr);
			Date dateNext = stringToDate(format, nextDateStr);
			return isOverDay(dateFront, dateNext, type, isContainEqual);
	}
	
	/**
	 * 是否nextDay大于frontDay
	 * @param frontDate
	 * @param nextDate
	 * @param type	类型:DAY按日期判断,HOUR按小时判断,MINUTE按分钟判断
	 * @return
	 */
	public static boolean isOverDay(Date frontDate ,Date nextDate, OVERDAY_CHECK_TYPE type){
		return isOverDay(frontDate, nextDate, type, false);
	}
	
	public static boolean isOverDay(Date frontDate ,Date nextDate, OVERDAY_CHECK_TYPE type, boolean isContainEqual){
		if (frontDate == null || nextDate == null)
			return false;
		long checkSpaceRadix = ONE_MINUTE;
		switch(type){
			case DAY:
				checkSpaceRadix = ONE_DAY;
				break;
			case HOUR:
				checkSpaceRadix = ONE_HOUR;
				break;
			case MINUTE:
//				checkSpaceRadix = 60 * 1000;
				break;
		}
		//转换为标准时间
		long checkSpace = (nextDate.getTime() - frontDate.getTime()) / checkSpaceRadix;
		if(checkSpace > 0){
			return true;
		}else{
			if(checkSpace==0&&isContainEqual){
				return true;
			}
			return false;
		}
	}
}
